home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / c.lqr / MEMCLEAN.C < prev    next >
Text File  |  1985-06-03  |  9KB  |  257 lines

  1. /*
  2.  
  3.  
  4.               MEMORY CLEAN FOR THE IBM PERSONAL COMPUTER
  5.  
  6.                              Version 1.00
  7.                              May 3, 1983
  8.  
  9.                          Robert J. Beilstein
  10.                         413 Wells Avenue, West
  11.                     North Syracuse, New York 13212
  12.  
  13.  
  14. One of the unfortunate "features" of the IBM Personal Computer is
  15. that, while the 8088 processor will address 1024K of memory, the BIOS
  16. (and, thus, DOS) will only recognize the first 640K (on "regular"
  17. PC's, without the expansion box and ROM, 544K) of memory.
  18.  
  19. While there are a number of programs around which are able to ignore
  20. the memory size passed from DOS, and make use of the additional
  21. memory, there is still a fairly serious problem that needs to be
  22. addressed.
  23.  
  24. When the machine is powered up, the contents of memory are
  25. unpredictable.  In particular, there is probably only a 50%
  26. probability that any given memory location has the proper parity.
  27.  
  28. The ROM BIOS "initial reliability tests" write to both planar and I/O
  29. RAM during initialization.  This not only sets proper parity in the
  30. memory locations (this happens automatically when the locations are
  31. written into), it also tests the memory for proper operation (though,
  32. curiously, it never attempts to write  an odd-parity value).
  33.  
  34. Unfortunately, this setting and testing of memory only occurs in the
  35. first 640K (544K) of memory.  Thus, any additional memory in the
  36. system is left in an uninitialized state.
  37.  
  38. If a program attempts to reference a location in this uninitialized
  39. memory before first writing to it (extremely poor programming
  40. practice, it is true), then there is a 50% chance that the result will
  41. be a "PARITY CHECK 2".
  42.  
  43. This seems like an awfully stiff penalty to pay for a program bug, as
  44. it requires one to power down the machine in order to clear it.
  45.  
  46. MEMCLEAN is a program which will write an initial value (with good
  47. parity) into all of the memory locations which IBM misses.
  48.  
  49. When called without additional parameters, the program will clear the
  50. high memory from X'C0000' through X'EFFFF' (768K to 960K).
  51.  
  52. If a parameter of "544K" is specified, locations X'88000' through
  53. X'9FFFF' (544K to 640K) will be cleared.  This is for compatibility
  54. with older (non XT) PC's.
  55.  
  56. If "SEGA" is specified, then locations X'A0000' through X'AFFFF' are
  57. included.  This area is defined to be "reserved" by IBM, but is (for
  58. now) available for use.
  59.  
  60. Specifying "NOHIGH" will inhibit writing into the high memory area
  61. (X'C0000' through X'EFFFF').
  62.  
  63. Note that writing into nonexistent memory locations causes no problems
  64. (other than using up some time).  So there is no problem if there is
  65. memory only up to (say) 576K.
  66.  
  67. The following examples illustrate the use of MEMCLEAN:
  68.  
  69. 1.  A PC/XT with memory in the high area, but not in the "reserved"
  70. area:
  71.  
  72. A>memclean
  73.  
  74.  
  75. 2.  A "regular" PC with 704K of contiguous memory (i.e. up through
  76. X'AFFFF'):
  77.  
  78. A>memclean sega 544k nohigh
  79.  
  80. 3.  A "regular" PC with every available memory location populated:
  81.  
  82. A>memclean 544k sega
  83.  
  84. 4.  A PC/XT with 704K of contiguous memory:
  85.  
  86. A>memclean sega nohigh
  87.  
  88.  
  89. Permission is given to use and copy this program and documentation
  90. freely, as long as no charge is made for its distribution or use, and
  91. as long as the notices and copyright statements in the program and
  92. documentation are left intact.  For complete details of the terms and
  93. conditions, please see the source code.
  94.  
  95. All other rights are reserved.  Program and documentation Copyright
  96. (C) Robert J. Beilstein, 1983.
  97.  
  98.  
  99.  
  100.  
  101.  
  102.         MEMORY CLEAN PROGRAM FOR THE IBM PERSONAL COMPUTER
  103.         Version 1.00  3 May 1983
  104.  
  105.         COPYRIGHT (C) ROBERT J. BEILSTEIN, 1983
  106.  
  107.                       N O T I C E
  108.  
  109.       This program is supplied for your personal and
  110.       non-commercial use only. No commercial use permitted.
  111.       Users of this program are granted limited rights to
  112.       reproduce and distribute this program, provided
  113.       the following conditions are met:
  114.  
  115.       1) This program must be supplied in original form,
  116.          with no modifications.
  117.       2) Notices contained in this source file, and those
  118.          produced by the executable program, must not be
  119.          altered or removed.
  120.       3) This program may not be sold. Providing this
  121.          program for consideration of any sort, including
  122.          copying or distribution fees, is prohibited.
  123.       4) This program may not be used on timesharing
  124.          systems where fees are charged for access,
  125.          or or supplied as part of any other form of
  126.          rental access computing, without the express
  127.          written permission of the author.
  128.  
  129.       PLEASE SEND PROBLEM REPORTS AND SUGGESTIONS
  130.       TO:
  131.             ROBERT J. BEILSTEIN
  132.             413 Wells Avenue, West
  133.             North Syracuse, New York 13212
  134.  
  135.         This program is designed to be run immediately following
  136.         powerup, and will fill all of expansion memory with good-parity
  137.         data (thus avoiding problems with spurious parity checks
  138.         if uninitialized memory is read).
  139.  
  140.         The program will write to all available memory locations
  141.         above the 640K the ROM BIOS knows about.  That is:
  142.  
  143.         X'C0000' --> X'EFFFF'
  144.  
  145.         In addition, if 'SEGA' is specified on the command line,
  146.         locations X'A0000' --> X'AFFFF' will be initialized.
  147.  
  148.         Also, for compatibility with pre-XT machines which have
  149.         a limit on DOS-addressible RAM of 544K, specifying '544K'
  150.         on the command line will start clearing at X'88000'.
  151.  
  152. */
  153.  
  154. #include <stdio.h>
  155.  
  156. #define WRITE_DATA 0xaaaa   /* memory initialization value */
  157.  
  158. main(argc,argv)     /* define entry point */
  159.  
  160. int argc;           /* count of function arguments */
  161. char *argv[];       /* pointer array to argument strings */
  162. {
  163.     unsigned int cur_segment;           /* current segment pointer */
  164.     unsigned int cur_offset;            /* current offset within segment */
  165.     unsigned int start_segment=0xa000;  /* starting segment */
  166.     unsigned int start_offset=0;        /* starting offset within segment
  167.                                            used to start 544k seg on 32k
  168.                                            boundary */
  169.  
  170.                                         /* a bunch of useful flags */
  171.         unsigned is_xt = 1;             /* if set, start at 640k */
  172.         unsigned resv_ok = 0;           /* if set, clear reserved memory
  173.                                            between X'A0000' and X'AFFFF' */
  174.         unsigned no_high = 0;           /* if set, do not initialize
  175.                                            X'C0000' or above */
  176.         unsigned good_parm;             /* current parameter valid */
  177.  
  178.     int i;                              /* the canonical temporary */
  179.  
  180.     unsigned long bot,top;              /* for displaying limit values */
  181.  
  182.     printf("\nMEMCLEAN V1.00, COPYRIGHT (C) Robert J. Beilstein, 1983\n\n");
  183.  
  184.     for (i = 1;i < argc;i++)            /* check invocation parms */
  185.     {
  186.         good_parm = 0;                  /* reset good parm flag */
  187.  
  188.         if (!strcmp(argv[i],"544k") && strcmp(argv[i],"544K"))
  189.         {
  190.             is_xt = 0;                  /* start at X'88000' */
  191.  
  192.             good_parm = 1;
  193.         }
  194.  
  195.         if (!strcmp(argv[i],"sega") && strcmp(argv[i],"SEGA"))
  196.         {
  197.  
  198.             resv_ok = 1;                /* do X'A0000' --> X'AFFFF' */
  199.  
  200.             good_parm = 1;
  201.  
  202.         }
  203.  
  204.         if (!strcmp(argv[i],"nohigh") && strcmp(argv[i],"NOHIGH"))
  205.         {
  206.  
  207.             no_high = 1;                /* skip X'C0000' --> X'EFFFF'  */
  208.  
  209.             good_parm = 1;
  210.  
  211.         }
  212.  
  213.         if (!good_parm)                 /* execute if a bad parm given */
  214.             abort("INVALID PARAMETER TO <MEMCLEAN>:  \"%s\"\nVALID PARAMETERS\
  215.  ARE: \"544k\", \"sega\" and \"nohigh\"",argv[i]);
  216.     }
  217.  
  218.     /* now that parameters are decoded, we can start doing something useful */
  219.  
  220.     if (!is_xt)                         /* if "544K" specified, reset addr */
  221.     {
  222.  
  223.         start_segment = 0x8000;
  224.         start_offset = 0x8000;
  225.  
  226.     }
  227.  
  228.     for (cur_segment = start_segment;cur_segment < 0xf000;cur_segment+=4096)
  229.     {
  230.  
  231.         if ((!resv_ok) && cur_segment == 0xa000) continue;
  232.  
  233.         if (cur_segment == 0xb000) continue;    /* skip graphics ram */
  234.  
  235.         if (no_high && cur_segment >= 0xc000) break;    /* quit on "nohigh */
  236.  
  237.         bot = (unsigned long) cur_segment * 16 + start_offset;
  238.         top = (unsigned long) cur_segment * 16 + 65535;
  239.  
  240.         printf("INITIALIZING %lx --> %lx\n",bot,top);   /* show same */
  241.  
  242.         for (cur_offset = start_offset;;cur_offset+=2)
  243.         {
  244.             pokew(cur_offset,cur_segment,WRITE_DATA);
  245.  
  246.             if (cur_offset == 0xfffe) break;
  247.  
  248.         }
  249.  
  250.         start_offset = 0;               /* subsequently start at offset 0 */
  251.  
  252.     }
  253.  
  254.     printf("ALL REQUESTED MEMORY INITIALIZED\n");
  255.  
  256. }
  257.